package micro.beauty.common.tool.utils.support;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;

/**
* @Author:         liuliya
* @CreateDate:     2020/6/9 22:49
*/
public class XmlValidator {

    /** XML schema */
    private static final String XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";

    /** xsd约束 */
    private File xsd;

    /** 需要校验的xml */
    private File xml;

    /**
     * 构造方法
     *
     * @param xsd xsd约束文件
     * @param xml 需要校验的xml
     */
    public XmlValidator(File xsd, File xml) {
        setXsd(xsd);
        setXml(xml);
    }

    /**
     * 构造方法
     *
     * @param xsd xsd约束文件
     * @param xml 需要校验的xml
     */
    public XmlValidator(Path xsd, Path xml) {
        setXsd(xsd.toFile());
        setXml(xml.toFile());
    }

    /**
     * 根据xsd校验xml
     *
     * @return 校验结果集
     */
    public boolean validate() {
        FileInputStream fileInputStream = null;
        try {
            // 建立schema工厂
            SchemaFactory schemaFactory = SchemaFactory.newInstance(XML_SCHEMA);
            // 利用schema工厂，接收验证文档文件对象生成Schema对象
            Schema schema = schemaFactory.newSchema(xsd);
            // 通过Schema产生针对于此Schema的验证器，利用schenaFile进行验证
            Validator validator = schema.newValidator();
            // 得到验证的数据源
            fileInputStream = new FileInputStream(xml);
            Source source = new StreamSource(fileInputStream);
            // 开始验证，成功输出success!!!，失败输出fail
            validator.validate(source);
        } catch (Exception e) {
            System.out.println(xml.getName() + "校验不通过，请检查【" + xsd.getName() + "】详细约束规则：" + e.getMessage());
            return false;
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    /**
     * @return 获取 xsd属性值
     */
    public File getXsd() {
        return xsd;
    }

    /**
     * @param xsd 设置 xsd 属性值为参数值 xsd
     */
    public void setXsd(File xsd) {
        this.xsd = xsd;
    }

    /**
     * @return 获取 xml属性值
     */
    public File getXml() {
        return xml;
    }

    /**
     * @param xml 设置 xml 属性值为参数值 xml
     */
    public void setXml(File xml) {
        this.xml = xml;
    }


}
